﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Events;
using Microsoft.Practices.Unity;

using Might.Core.DOM;
using Might.Infrastructure.DOM;
using Might.Infrastructure.Events;
using Might.Infrastructure.Services;

using Might.Core.AuthenticationServiceFrontend;
using Might.Core.SvnServiceFrontend;

namespace Might.Core.Services {

    ///<summary>
    /// fake authentication service
    ///</summary>
    public class AuthenticationService : Infrastructure.Services.IAuthenticationService {
    
        private readonly IUnityContainer container;
        IProgressToken progressToken;

        public AuthenticationService() {
            this.container = CoreServices.Container;            
            CoreServices.EventAggregator.GetEvent<LoginEvent>().Subscribe(LoginEventHandler, ThreadOption.UIThread, false);
            CoreServices.EventAggregator.GetEvent<LogoutEvent>().Subscribe( LogoutEventHandler , ThreadOption.UIThread , false );
        }
        

        ///<summary>
        ///</summary>
        ///<param name="info"></param>
        public void LoginEventHandler(LoginData info) {

            progressToken = container.Resolve<IProgressService>().ProgressCreate( typeof( LoginEvent ) , container.Resolve<IDom>());
            progressToken.ProgressStart("Loging user: " + info.Name);

            var authenticationClient = new AuthenticationServiceClient();
            authenticationClient.GetAuthenticationCompleted += authenticationClient_GetAuthenticationCompleted;

            Authentication Login = new Authentication {Username = info.Name, Password = info.passwd};

            authenticationClient.GetAuthenticationAsync(Login);
            progressToken.Progress(10, "Async login request finished");
            
        }

        void authenticationClient_GetAuthenticationCompleted(object sender, GetAuthenticationCompletedEventArgs e) {
            
            if (e.Error != null) {
                string error = "Login failed! Reason: " + e.Error.Message;
                progressToken.ProgressEnd( ProgressResult.Fail , error );
                return;
            }
            else if (e.myFault != null){
                string error = "Login failed! Reason: " + e.myFault.Message;
                progressToken.ProgressEnd(ProgressResult.Fail, error);
                return;
            }

            progressToken.Progress( 50 , "User informations obtained succesfully" );

            UserInfo ui = new UserInfo { Name = e.Result.Username, PassHash = e.Result.Password };
            
            // new user has been added to root
            container.Resolve<IDom>().InsertChild( GroupNames.User , ui );            
            
            foreach (SvnRecord server in e.Result.SvnList) {
                SvnFileSystemRoot svnServer = new SvnFileSystemRoot();
                // TODO: SvnServer ted nema jmeno, tak jeho jmenem bude zatim adresa                    
                svnServer.Name = server.SvnAddress;
                svnServer.Uri = server.SvnAddress;
                svnServer.Username = server.SvnUsername;
                svnServer.Password = server.SvnPassword;
                svnServer.Parent = ui;
                ui.InsertChild( GroupNames.FileSystemRoot , svnServer );
            }            
                
            progressToken.ProgressEnd( ProgressResult.Success , "Login finished" );
        }


        ///<summary>
        ///</summary>
        ///<param name="info"></param>
        public void LogoutEventHandler(IUserInfo info) {

            progressToken = container.Resolve<IProgressService>().ProgressCreate(typeof(LogoutEvent), info);

            progressToken.ProgressStart("Loging out user: " + info.Name);

            progressToken.Progress(25, "Doing stuff, destroying DOM, AST, etc...");

            //Thread.Sleep(500); // emulating waiting                       

            var svnClient = new SvnServiceClient();
            svnClient.CleanCompleted += new EventHandler<CleanCompletedEventArgs>(svnClient_CleanCompleted);

            svnClient.CleanAsync(info.Name);
            progressToken.Progress(75, "Removing temporary files on server.");

        }

        void svnClient_CleanCompleted(object sender, CleanCompletedEventArgs e) {
            if (e.Error != null) {
                string error = "Problem with cleaning temporary files directory on server! Message: " + e.Error.Message;
                progressToken.ProgressEnd(ProgressResult.Success, "Logout finished, but server error occurred: " + error);
                return;
            }
            progressToken.ProgressEnd(ProgressResult.Success, "Logout finished");
        }
    }
}